/**
 * 权限相关状态管理
 * 处理路由权限、用户权限等逻辑
 */

import { ref } from 'vue'
import { defineStore } from 'pinia'
import type { BaseRoute } from '@/types/router'
import type { UserInfo } from '@/api/core/login'
import { getMenuListApi } from '@/api/core/prmissions'
import { STORAGE_LOGIN_TOKEN, STORAGE_USER_INFO } from '@/constants/localKey'

export const useAccessStore = defineStore('access', () => {
    const routes = ref<BaseRoute[]>([])
    const isRoutesLoaded = ref(false)
    const loading = ref(false)
    const accessMenu = ref<BaseRoute[]>([])
    const token = ref<string>(localStorage.getItem(STORAGE_LOGIN_TOKEN) || '')
    const userInfo = ref<UserInfo | null>(JSON.parse(localStorage.getItem(STORAGE_USER_INFO) || '{}') || '')

    /**
     * 模拟接口请求获取路由数据
     * @returns Promise<BaseRoute[]>
     */
    const fetchRoutes = async (): Promise<BaseRoute[]> => {
        loading.value = true

        try {
            // 获取菜单列表
            const res = await getMenuListApi()
            return res.data as BaseRoute[]
        } finally {
            loading.value = false
        }
    }

    /**
     * 初始化路由数据
     * @returns Promise<BaseRoute[]>
     */
    const initRoutes = async (): Promise<BaseRoute[]> => {
        if (isRoutesLoaded.value) {
            return routes.value
        }

        try {
            const routeData = await fetchRoutes()
            // 判断当前路由和routeData是否一致
            if (routes.value.length === routeData.length) {
                return routes.value
            }

            routes.value = routeData
            isRoutesLoaded.value = true
            return routeData
        } catch (error) {
            console.error('获取路由数据失败:', error)
            throw error
        }
    }

    /**
     * 重置状态（用于登出等场景）
     */
    const reset = (): void => {
        routes.value = []
        isRoutesLoaded.value = false
        loading.value = false
        token.value = ''
        userInfo.value = null
        localStorage.removeItem(STORAGE_LOGIN_TOKEN)
        localStorage.removeItem(STORAGE_USER_INFO)
    }

    /**
     * 设置登录 token
     */
    const setToken = (newToken: string): void => {
        token.value = newToken
        if (newToken) {
            localStorage.setItem(STORAGE_LOGIN_TOKEN, newToken)
        } else {
            localStorage.removeItem(STORAGE_LOGIN_TOKEN)
        }
    }

    /**
     * 设置用户信息
     */
    const setUserInfo = (info: UserInfo | null): void => {
        userInfo.value = info
        if (info) {
            localStorage.setItem(STORAGE_USER_INFO, JSON.stringify(info))
        } else {
            localStorage.removeItem(STORAGE_USER_INFO)
        }
    }

    /**
     * 根据权限过滤路由（可扩展）
     * @param routes 路由数组
     * @param permissions 权限数组
     * @returns 过滤后的路由数组
     */
    const filterRoutesByPermission = (routes: BaseRoute[], permissions: string[] = []): BaseRoute[] => {
        // 这里可以根据用户权限过滤路由
        // 当前返回所有路由，后续可以根据实际需求扩展

        // 示例：根据权限递归过滤路由
        const filterRoutes = (routeList: BaseRoute[]): BaseRoute[] => {
            return routeList.filter((route) => {
                // 如果路由有权限要求，检查用户是否有对应权限
                if (route.meta.permission && !permissions.includes(route.meta.permission)) {
                    return false
                }

                // 递归过滤子路由
                if (route.children.length > 0) {
                    route.children = filterRoutes(route.children)
                }

                return true
            })
        }

        return filterRoutes(routes)
    }

    /**
     * 设置访问菜单
     * @param menu 菜单
     */
    const setAccessMenu = (menu: BaseRoute[]): void => {
        accessMenu.value = menu
    }

    /**
     * 退出登录
     */
    const logout = (): void => {
        reset()
        // 清空所有本地存储
        localStorage.clear()
        // 这里可以添加其他清理逻辑，比如清除缓存等
    }

    return {
        routes,
        setAccessMenu,
        accessMenu,
        isRoutesLoaded,
        loading,
        fetchRoutes,
        initRoutes,
        reset,
        filterRoutesByPermission,
        token,
        userInfo,
        setToken,
        setUserInfo,
        logout,
    }
})
